package demo03_collection

import scala.util.{Failure, Random, Success}

object Demo02_singleItemCollection {
  /**
   * 一元集合：元素的个数不超过1个的集合
   */

  //1.Option集合：表示值的存在于不存在
  //  Some(x) 表示值存在    None 表示值不存在
  def unitSet_option(): Option[Int] = {

    //1.1 在不明确某个值或变量是否有值的情况下，可以使用Option对其进行判断
    //    如果为null 返回的是None；如果不为null 返回的是 Some(x)
//    val str:String = null
//    println(Option(str))

    val rand = new Random()
    val number = rand.nextInt()

    println(s"number:${number}")

    //1.2 从业务逻辑上规定某种情况下，为 None，不是真正的没有值
    if (number <= 0) {
      None
    } else {
      Some(number)
    }
  }

  /**
   * 关于Option类型的数据(返回值)的几种处理方式
   */
  def unitSet_option_process() = {

    val option:Option[Int] = unitSet_option()

    //1.match...case 比较麻烦但是灵活
    option match {
      case Some(value) => println("you are right")
      case None => println("you are wrong")
    }

    //2.fold 如果接收到的是None，输出的是第一个参数的默认值；如果接收到的是Some，按第二个参数的函数执行
    val res_fold = option.fold(0)(s=>s)
    println(res_fold)

    //3.getOrElse 如果接收到的是None，输出的是第一个参数的默认值；如果接收到的是Some，默认原样输出
    val res_getOrElse = option.getOrElse(0)
    println(res_getOrElse)

    //4.orElse 与getOrElse用法一致，区别是依然以Option类型返回
    val res_orElse = option.orElse(Some(0))
    println(res_orElse)
  }

  //2.Try集合 表示代码执行成功或失败
  //  Success(正确执行的返回值) 表示代码执行成功    Failure(错误信息) 表示代码执行失败
  def unitSet_try(): util.Try[Int] = {
    val array = Array(1, 2, 3, 4, 5)

    val rand = util.Random
    val flag = rand.nextBoolean()

    if(flag){
      util.Try(array(3))
    } else{
      util.Try(array(6))
    }
  }

  /**
   * 对于try类型的一元集合的处理方式
   */
  def unitSet_try_process() = {

    val utilTry: util.Try[Int] = unitSet_try()

    //1.match...case
    utilTry match {
      case Failure(exception) => println("出错了吧 活该")
      case Success(value) => println("不应该呀")
    }

    //2.foreach 只针对Success生效，对Failure只能返回为Unit
    utilTry.foreach(println)

    //3.getOrElse
    println(utilTry.getOrElse("error"))

    //4.orElse
    println(utilTry.orElse(util.Try(Success("error"))))

    //5.Try类型可以转成Option类型
    println(utilTry.toOption)
  }

  /**
   * option和try集合的案例
   */
  def unitSet() = {
    val input = "123 "
    val result = util.Try(input.toInt) orElse util.Try(input.trim.toInt)
    result foreach {
      r => println(s"Parsed '$input' to $r!")
    }
    val x = result match {
      case util.Success(x) => Some(x)
      case util.Failure(ex) => {
        println(s"Couldn't parse input '$input'")
        None
      }
    }
  }

  //3.Either集合  逻辑上的正确与错误 含有主观的情况在
  //  Left 通常表示错误或异常情况      Right 表示正常的结果
  def unitSet_either(): Either[String, String] = {

    val phoneNumberHeader = List("138", "139", "130")
    val phoneNumber = "13812345678"

    if (phoneNumber.length == 11) {
      if (phoneNumberHeader contains phoneNumber.substring(0, 3)) {
        Right("手机号正确输入")
      } else {
        Left("没查询到此手机号")
      }
    } else {
      Left("手机号格式错误")
    }
  }

  /**
   * either 的处理方法
   */
  def unitSet_either_process() = {
    val either:Either[String,String] = unitSet_either()
    println(either)
    either.foreach(println)
    println(either.toOption)
  }


  def main(args: Array[String]): Unit = {
    unitSet_either_process()
  }

}
